package com.example.runtime;

import com.example.service.StudentService;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 01
 * @date 2019-10-05
 **/
@Slf4j
public class CommandRunner {
    /**
     * 服务名称到服务对象的映射
     */
    private Map<String, Object> services = new HashMap<>();

    /**
     * 服务提供的方法
     */
    private Map<String, Map<String, Method>> methods = new HashMap<>();

    /**
     * 服务名称到服务接口类的映射
     */
    private Map<String, Class<?>> serviceType = Map.of("student", StudentService.class);

    public CommandRunner() {
        serviceType.forEach((name, cls) ->
                // 查找并加载服务类对象
                ServiceLoader.load(cls).findFirst().ifPresent(obj -> {
                    services.put(name, obj);
                    // 加载服务提供的方法
                    methods.put(name, Stream.of(
                            obj.getClass().getDeclaredMethods()
                    ).collect(Collectors.toMap(Method::getName, Function.identity())));
                })
        );
    }

    /**
     * @param service 服务名称
     * @param task    方法名称
     * @param args    方法参数
     */
    public void run(String service, String task, List<Object> args) {
        Object serviceObj = services.get(service);
        Method method = methods.get(service).get(task);
        try {
            Object result = method.invoke(serviceObj, args);
            System.out.println(result.toString());
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
